#include <iostream>
#include <string>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <cstring>

#define SIZE 1024

//info proc mmaping
//0x7ffff7ffa000     0x7ffff7ffb000     0x1000        0x0  rw-s   /home/lhx/linux_code/112/mmap/log.txt

int main(int argc,char *argv[])
{
    if(argc != 2)
    {
        std::cout << "Usage: " << argv[0] << "filename" << std::endl;
        exit(1);
    }

    //1.打开文件
    int fd = ::open(argv[1],O_CREAT | O_RDWR, 0666);
    if(fd < 0)
    {
        std::cerr << "open file error" << std::endl;
        exit(2);
    }
    //2.设置大小
    // 默认⽂件⼤⼩是0，⽆法和mmap进⾏正确映射，这⾥需要调整⽂件⼤⼩，⽤0值填充
    ::ftruncate(fd, SIZE);

    //3.打开映射
    // // 内存映射文件
    // char* map = static_cast<char*>(mmap(
    //     nullptr,        // 让系统选择映射地址
    //     size,           // 映射大小
    //     PROT_READ | PROT_WRITE,  // 可读可写
    //     MAP_SHARED,     // 更改会写回文件,MAP_SHARED是可以对底层文件进行修改，MAP_PRIVATE不对文件进行修改
    //     fd,             // 文件描述符
    //     0               // 从文件起始位置开始映射
    // ));
    char *mmapaddr = (char*)::mmap(nullptr,SIZE,PROT_READ | PROT_WRITE,MAP_SHARED, fd, 0);
    if(mmapaddr == MAP_FAILED)
    {
        perror("mmap");
        exit(3);
    }

    //4.文件操作
    for(int i = 0; i < SIZE; i++)
    {
        mmapaddr[i] = 'a' + i%26;
    }

    //5.关闭映射
    ::munmap(mmapaddr,SIZE);
    //6.关闭文件
    ::close(fd);
    return 0;
}